import { Subscription } from 'rxjs';
import { AfterViewInit, Component, OnInit, OnDestroy } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { AuthorityService } from 'src/app/common/authority/authority.service';
import { WorkflowPageService } from 'src/app/common/page-render/workflow-page-container/workflow-page.service';
import { Authority, DataRegister, User } from 'src/app/models';
import { BaseService, DataRegisterService } from 'src/app/services';
import { AddressService } from 'src/app/services/address.service';
import { EventManagerService } from 'src/app/services/event-manager.service';
import { OrganizationService } from 'src/app/services/organization.service';
import { UploadService } from 'src/app/services/upload.service';
import { PermitConfig, PermitConfigId } from '../../../models';
import { EngineService } from '../../../services/engine.service';
import { BaseFieldComponent } from '../base-field/base-field.component';
import { AuditOption } from './model/auditOption';
import { AuditService } from './audit.service';
import { AuditItem } from './model/auditItem';

@Component({
  selector: 'zepride-audit',
  templateUrl: './audit.component.html',
  styleUrls: ['./audit.component.less', '../field.common.less']
})
export class AuditComponent extends BaseFieldComponent implements OnInit, AfterViewInit, OnDestroy {

  auditSubmitSub: Subscription;
  auditResultChangedSub: Subscription;
  auditChangedSub: Subscription;
  workflowUpdatedSub: Subscription;

  dataRegister: DataRegister;

  options: AuditOption = {
    auditLevel: 1,
    isSubmit: false,
    isFinish: false,
    auditItems: [],
    auditLevelOptions: []
  };

  currentAuditItem: AuditItem;
  backAuditItemIndex = 0;

  permitConfig: PermitConfig[] = [
    { mode: 'query', permitId: '查看', permitName: '', authObjectId: '' },
    { mode: 'edit', permitId: '编辑', permitName: '', authObjectId: '' }
  ];
  isAuthorized = true;
  specialAuths: Authority[] = [];

  constructor(
    protected engineService: EngineService,
    protected baseSvr: BaseService,
    protected eventSvr: EventManagerService,
    protected orgSvr: OrganizationService,
    public uploadService: UploadService,
    protected msg: NzMessageService,
    public addSvr: AddressService,
    protected authorityService: AuthorityService,
    protected wsvr: WorkflowPageService,
    protected auditSvr: AuditService,
    protected dataRegisterService: DataRegisterService
  ) {
    super(engineService, baseSvr, eventSvr, orgSvr, uploadService, msg, dataRegisterService);
  }

  ngOnDestroy(): void {
    if (this.auditSubmitSub) {
      this.auditSubmitSub.unsubscribe();
    }
    if (this.auditChangedSub) {
      this.auditChangedSub.unsubscribe();
    }
    if (this.auditResultChangedSub) {
      this.auditResultChangedSub.unsubscribe();
    }
  }

  ngOnInit() {
    // console.log('AuditComponent', this.componentData);
    if (!this.options) {
      this.options = {} as any;
    }
    if (this.bindData) {
      this.options = this.bindData;
      const item = this.getCurrentAuditItem();
      this.onAuditItemChange(item);
    } else {
      this.options.auditLevel = this.componentData.extends.auditLevel;
      this.options.auditLevelOptions = this.componentData.extends.auditLevelOptions;
    }
    if (!this.options.isFinish) {
      this.wsvr.auditInit.next();
    }

    this.auditSubmitSub = this.wsvr.auditSubmit.subscribe(() => {
      this.subAuditHandle();
    });

    this.auditResultChangedSub = this.auditSvr.auditResultChanged.subscribe(data => {
      this.setBindData(this.options);
    });

    this.auditChangedSub = this.wsvr.auditChanged$.subscribe(() => {
      this.options = this.bindData;
    });

    this.workflowUpdatedSub = this.wsvr.workflowUpdated.subscribe(dataRegister => {
      if (!dataRegister) {
        return;
      }
      this.dataRegister = dataRegister;
    });
  }

  ngAfterViewInit() {
    setTimeout(() => {
      const authData = this.setAuthorityData();
      this.zeprideAuthorityData = {
        ...authData,
        afterChecked: this.afterAuthChecked.bind(this)
      };
    });
  }

  async subAuditHandle() {
    const loginUser = JSON.parse(localStorage.getItem('userInfo'));
    if (this.currentAuditItem && ['pass', 'return', 'unpass'].indexOf(this.currentAuditItem.conclusion) === -1) {
      this.msg.error('请填写审核结论');
      return;
    }
    if (this.currentAuditItem && this.currentAuditItem.conclusion === 'return' && !this.currentAuditItem.backType) {
      this.msg.error('请填写退回层级');
      return;
    }
    if (this.options.isSubmit) {
      // 审核
      this.currentAuditItem.createTime = Date.now();
      this.currentAuditItem.auditName = loginUser.name;
      this.currentAuditItem.isCurrent = false;
      this.currentAuditItem.isFinish = true;
      if (this.currentAuditItem.conclusion === 'return') {
        // 回退
        this.auditResultReturn();
      } else if (this.currentAuditItem.conclusion === 'pass') {
        // 通过
        this.auditResultPass();
      } else if (this.currentAuditItem.conclusion === 'unpass') {
        //  不通过审核，直接终止项目
        await this.dataRegisterService.updateDataRegisterStatus(this.dataRegister.id, 'closed');
        this.msg.success('项目终止成功！');
        location.reload();
      }
    } else {
      // 提交审核
      this.submitAudit();
    }
    const item = this.getCurrentAuditItem();
    this.onAuditItemChange(item);
    this.dataModel[this.componentData.bindField] = this.options;
  }

  private auditResultReturn() {
    this.clearCurrent();
    if (this.currentAuditItem.backType === 'gradually') {
      // 逐级退回
      if (this.currentAuditItem.index == 1) {
        // 已经是第一级审核
      } else {
        // 是第二级以上的审核
        this.currentAuditItem = this.options.auditItems[this.currentAuditItem.index - 1];
      }
    } else if (this.currentAuditItem.backType === 'appoint') {
      for (let index = this.backAuditItemIndex; index < this.options.auditItems.length; index++) {
        if (index === 0) {
          continue;
        }
        const item = this.options.auditItems[index];
        this.initAuditItem(item, 'return');
      }
      // 退回到指定审核层级
      this.currentAuditItem = this.options.auditItems[this.backAuditItemIndex];
    }
    let conclusion = 'wait';
    if (this.backAuditItemIndex === 0) {
      conclusion = 'pass';
    }
    this.currentAuditItem = this.initAuditItem(this.currentAuditItem, conclusion);
  }
  /**
   * 初始化节点信息
   */
  initAuditItem(item: AuditItem, conclusion: any = 'wait') {
    item.isFinish = false;
    item.isCurrent = true;
    item.conclusion = conclusion;
    item.createTime = null;
    item.opinion = 'no';
    item.opinionValue = null;
    return item;
  }

  private auditResultPass() {
    if (this.isAuditCompleted()) {
      // 是否通过了所有的审核
      this.options.isFinish = true;
      // 发起审核完成的事件
      this.eventSvr.callEvents('audit.finish', {});

      this.wsvr.auditFinish$.next();
    }
    else {
      // 没有通过所有的审核
      const unpassList = this.options.auditItems.filter(x => x.conclusion !== 'pass');
      this.currentAuditItem = unpassList[0];
      this.currentAuditItem.isCurrent = true;
      this.currentAuditItem.isFinish = false;
      this.currentAuditItem.conclusion = 'wait';
      this.currentAuditItem.opinion = 'no';
      this.currentAuditItem.opinionValue = null;
    }
  }

  private isAuditCompleted() {
    const list = this.options.auditItems.filter(x => x.conclusion === 'pass');
    return list.length === this.options.auditItems.length;
  }

  private submitAudit() {
    this.options.isSubmit = true;
    const loginUser: User = JSON.parse(localStorage.getItem('userInfo'));
    this.initAuditItems(loginUser);
    for (const item of this.options.auditLevelOptions) {
      const index = this.options.auditItems.length;
      this.options.auditItems.push({
        name: item.alias,
        auditName: loginUser.name,
        conclusion: 'wait',
        isFinish: false,
        nodeType: 'audit',
        index,
        opinion: 'no',
        isCorrective: item.isCorrective
      });
    }
  }
  /**
   * 添加提交节点
   */
  initAuditItems(user: User) {
    this.options.auditItems = [
      {
        submitName: user.name,
        name: '提交',
        index: 0,
        conclusion: 'pass',
        nodeType: 'submit',
        isFinish: true,
        createTime: Date.now()
      }
    ];
  }

  private clearCurrent() {
    this.options.auditItems.forEach(x => x.isCurrent = false);
  }

  private getCurrentAuditItem() {
    const has = this.options.auditItems.find(x => x.isCurrent && x.nodeType === 'audit');
    if (has) {
      this.currentAuditItem = has;
    } else {
      this.clearCurrent();
      this.options.auditItems[1].isCurrent = true;
      this.currentAuditItem = this.options.auditItems[1];
      this.currentAuditItem.index = 1;
    }
    this.options.auditItems.forEach((item, index) => {
      const isAuthorized = this.checkAuditItem(item.name);
      item.permissionDenied = !isAuthorized;
    });
    return this.currentAuditItem;
  }

  onAuditItemChange(item: AuditItem) {
    this.wsvr.auditCurrentItemChanged$.next(item);
  }

  private formatNum(index: number) {
    const list = new Array('', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
    return list[index];
  }

  afterAuthChecked(params: {
    permitId: PermitConfigId;
    isAuthorized: boolean;
  }) {
    if (!params.isAuthorized && params.permitId === '查看') {
      this.isAuthorized = false;
    }
  }
  /**
   * 检测审核的权限
   */
  checkAuditItem(permitId: string) {
    const isAuthorized = this.authorityService.checkAuthority({
      refObjectId: this.tmpComItemId,
      permitId,
      refObjectType: 'TmpComItem'
    });
    return isAuthorized;
  }
}
